// ignore_for_file: use_function_type_syntax_for_parameters

import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_cli/utils/loading_util.dart';
import 'package:flutter_cli/utils/log.dart';
import 'package:flutter_cli/utils/sp_util.dart';
import 'package:get/get.dart' hide FormData, MultipartFile;
import 'package:flutter_cli/config/config.dart';
import 'package:flutter_cli/widgets/widget.dart';

class DioUtil {
  /// 连接超时时间
  static const int CONNECT_TIMEOUT = 60 * 1000;

  /// 响应超时时间
  static const int RECEIVE_TIMEOUT = 60 * 1000;

  static DioUtil? _instance;
  static Dio _dio = Dio();

  Dio get dio => _dio;

  DioUtil._internal() {
    _instance = this;
    _instance!._init();
  }

  factory DioUtil() => _instance ?? DioUtil._internal();

  static DioUtil? getInstance() {
    _instance ?? DioUtil._internal();
    return _instance;
  }

  /// 取消请求token
  late CancelToken _cancelToken = CancelToken();

  void changeToken(CancelToken token) {
    _cancelToken = token;
  }

  /// 取消网络请求
  void cancelRequests({CancelToken? token}) {
    if (token != null) {
      token.cancel("cancelled");
    } else {
      _cancelToken.cancel("cancelled");
    }
  }

  _init() {
    /// 初始化基本选项
    BaseOptions options = BaseOptions(
        baseUrl: Config.host,
        connectTimeout: CONNECT_TIMEOUT,
        receiveTimeout: RECEIVE_TIMEOUT);

    /// 初始化dio
    _dio = Dio(options);
  }

  void getHttp(url, data,  back(val),
      {option,
      bool showLoading = false,
      bool verify = true,
      Function()? complete,
      bool isLogout = false,
      CancelToken? cancelToken}) async {
    if (showLoading) LoadingUtils.show(msg: '加载中...');
    Options option = Options();
    if (verify) {
      var authorization = readStringData('Authorization');
      option = isLogout
          ? Options(headers: {
              'Authorization': authorization,
              'X-Requested-With': 'XMLHttpRequest'
            })
          : Options(headers: {'Authorization': authorization});
      Log.d("header:${option.headers}");
    }
    var urls = Config.host + url;
    var params = data.isEmpty ? <String, dynamic>{} : data;
    Log.d("request_url:$urls");
    Log.d("request_params:$params");
    try {
      var response = await _dio.get(urls,
          queryParameters: params,
          options: option,
          cancelToken: cancelToken ?? _cancelToken);
      Map<dynamic, dynamic> res = jsonDecode(response.toString());
      Log.d("response:$res");
      if (showLoading) LoadingUtils.dismiss();
      if (res['code'] == 402 || res['code'] == 401) {
        hkShowToast(res['message']);
        removeKey('Authorization');
        Get.offAllNamed('/login');
      } else if (res['code'] == 400 && (res['message'] == '请登录')) {
        hkShowToast(res['message']);
        removeKey('Authorization');
        Get.offAllNamed('/login');
      } else {
        back(res);
      }
      if (complete != null) {
        complete();
      }
    } catch (e) {
      if (complete != null) {
        complete();
      }
      if (showLoading) LoadingUtils.dismiss();
    }
  }

  void postHttp(url, data,  back(val),
      {option,
      showLoading = false,
      verify = true,
      isLogout = false,
      CancelToken? cancelToken}) async {
    if (showLoading) LoadingUtils.show(msg: '加载中...');
    Options option = Options();
    if (verify) {
      var authorization = readStringData('Authorization');

      option = isLogout
          ? Options(headers: {
              'Authorization': authorization,
              'X-Requested-With': 'XMLHttpRequest'
            })
          : Options(headers: {'Authorization': authorization});
      Log.d("header:${option.headers}");
    }
    var urls = Config.host + url;
    var params = data.isEmpty ? <String, dynamic>{} : data;
    Log.d("request_url:$urls");
    Log.d("request_params:$params");
    try {
      var response = await _dio.post(urls,
          data: params,
          options: option,
          cancelToken: cancelToken ?? _cancelToken);
      //queryParameters: datas,
      Map<dynamic, dynamic> res = jsonDecode(response.toString());
      print(res);
      if (showLoading) LoadingUtils.dismiss();
      if (res['code'] == 402 || res['code'] == 401) {
        hkShowToast(res['message']);
        removeKey('Authorization');
        Get.offAllNamed('/login');
      } else if (res['code'] == 400 && (res['message'] == '请登录')) {
        hkShowToast(res['message']);
        removeKey('Authorization');
        Get.offAllNamed('/login');
      } else {
        back(res);
      }
    } catch (e) {
      print(e);
      // ShowMsg('网络拥挤！');
      if (showLoading) LoadingUtils.dismiss();
    }
  }

  uploadImg(url, data, void back(val),
      {option,
      showLoading = false,
      verify = true,
      CancelToken? cancelToken}) async {
    if (showLoading) LoadingUtils.show(msg: '加载中...');
    Options option = Options();
    if (verify) {
      var Authorization = readStringData('Authorization');
      option = Options(headers: {
        'Authorization': Authorization,
        'Content-Type': 'multipart/form-data'
      });
      print(Authorization);
    }
    print(data['image']);
    String path = data['image'];
    var name = path.substring(path.lastIndexOf("/") + 1, path.length);
    var suffix = name.substring(name.lastIndexOf(".") + 1, name.length);
    FormData formData =
        FormData.fromMap({"image": await MultipartFile.fromFile(path)});
    var urls = Config.host + url;

    try {
      var response = await _dio.post(urls,
          data: formData,
          options: option,
          cancelToken: cancelToken ?? _cancelToken);
      Map<dynamic, dynamic> res = jsonDecode(response.toString());
      print(res);
      if (showLoading) LoadingUtils.dismiss();
      if (res['code'] == 402 || res['code'] == 401) {
        hkShowToast(res['msg']);
        removeKey('token');
        Get.offAllNamed('/login');
      } else {
        back(res);
      }
    } catch (e) {
      print(e);
      if (showLoading) LoadingUtils.dismiss();
    }
  }

// @override
// void dispose() {
//   if (_cancelToken != null) {
//     if (_cancelToken?.isCancelled != true) _cancelToken?.cancel();
//     _cancelToken = null;
//   }
//   super.dispose();
// }
}
